function Promise (fn) {
  this.status = 'pending'
  this.msg = ''

  fn(function (msg) {
    this.status = 'resolve'
    this.msg = msg
  }.bind(this), function (msg) {
    this.status = 'reject'
    this.msg = msg
  }.bind(this))

  return this
}

Promise.prototype.then = function (resolve, reject) {
  if (this.status === 'resolve' && resolve) {
    resolve(this.msg)
  } else if (this.status === 'reject' && reject) {
    reject(this.msg)
  }
}

new Promise((resolve, reject) => {
  resolve('...')
}).then(res => {
  console.log(res)
}, res => {
  console.error(res)
})

// promise 构造函数
function LingPromise (fn) {
  let that = this
  that.status = 'pending'
  that.value = ''
  that.reason = ''
  that.onFulfilledCb = []
  that.onRejectedCb = []

  function resolve (value) {
    setTimeout (() => {
      if (that.status === 'pending') {
        that.status = 'fulfilled'
        that.value = value
        that.onFulfilledCb.map( item => {
          item(that.value)
        })
      }
    }, 0)
  }

  function reject (reason) {
    setTimeout(() => {
      if (that.status === 'pending') {
        that.status = 'rejected'
        that.reason = reason
        that.onRejectedCb.map( item => {
          item(that.reason)
        })
      }
    }, 0)
  }

  fn(resolve, reject)
}

LingPromise.prototype.then = function (onFulfilled, onRejected) {
  let that = this

  onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v
  onRejected = typeof onRejected === 'function' ? onRejected : r => r

  console.log(that.status)
  if (that.status === 'pending') {
    return new LingPromise((resolve, reject) => {
      that.onFulfilledCb.push(value => {
        try {
          let x = onFulfilled(value)
        } catch(e) {
          reject(e)
        }
      })

      that.onRejectedCb.push(reason => {
        try {
          let x = onRejected(reason)
        } catch(e) {
          reject(e)
        }
      })
    })
  }
}

new LingPromise((resolve, reject) => {
  setTimeout(() => {
    resolve('promise done')
  }, 2000)
})
.then(res => {
  console.log(res)
  new LingPromise((resolve, reject) => {
    setTimeout(() => {
      reject('promise else')
    }, 1000)
  })
  .then((res) => console.log(res), (msg) => console.log(msg))
})
